﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.Diagnostics;
using System.IO;
using System.Xml;

namespace Lon.Data.Station
{
    [XmlRoot("采集机配置")]
    public class SampleDevManager
    {
        [XmlIgnore]
        public Dictionary<int, SampleDevParam10> devDict = new Dictionary<int, SampleDevParam10>();
        [XmlElement("采集机")]
        public List<SampleDevParam10> Items = new List<SampleDevParam10>();

        public bool Add(SampleDevParam10 dev)
        {
            if (devDict.ContainsKey(dev.DevNo))
            {
                DevParamOut.OutMessage("添加采集机失败采集机已存在");
                return false;
            }
            devDict[dev.DevNo] = dev;
            Items.Add(dev);
            return true;
        }

        public bool SaveToXml(String path)
        {
            try
            {
                using (StreamWriter sw = new StreamWriter(path, false))
                {
                    XmlSerializer xmlSerializer = new XmlSerializer(typeof(SampleDevManager));
                    xmlSerializer.Serialize(sw, this);
                }
            }
            catch (System.Exception ex)
            {
                DevParamOut.OutWarnning("文件保存错误，可能为文件目录不存在或文件" + ex.Message + ex.StackTrace);
                return false;
            }
            return true;
        }

        public void LoadFormXml(String path)
        {
            SampleDevManager devManager = null;
            using (StreamReader sr = new StreamReader(path))
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(SampleDevManager));
                devManager = xmlSerializer.Deserialize(sr) as SampleDevManager;
            }
            for (int i = 0; i < devManager.Items.Count; i++)
            {
               this.Add(devManager.Items[i]);
            }
        }
    }

    public class SampleDevParam10
    {
        [XmlAttribute("采集机号")]
        public int DevNo;
        [XmlAttribute("预留字节")]
        public int resvbyte = 0;
        /// <summary>
        /// 区分采集机的类型是为了生成参数时使用不同的生成模板
        /// 1为主要采集开关量
        /// 2为主要采集模拟量
        /// 3为 模拟量加开关量 (道岔电流采集) 为同一配线标准 前三块板预留为开关量位置 
        /// 道岔启动继电器占用一块板 后面两块板用于定位 反位的实际采集 (非强制要求,有利于提高产品的人性化程度)
        /// 4为带智能传感器的采集机
        /// 
        /// 
        /// </summary>
        [XmlAttribute("采集机类型")]
        public int DevType = 1;
        [XmlAttribute("采集机类型描述")]
        public String Desp = "模拟量采集机带道岔电流";
        [XmlElement("采集板")]
        public List<SampleDevCardParam10> CardItems = new List<SampleDevCardParam10>();
        public SampleDevParam10()
        {
        }
        public SampleDevParam10(int devNo, int devType)
        {
            this.DevNo = devNo;
            this.DevType = devType;
            SampleDevCardParam10 card;
            switch (DevType)
            {
                case 0:
                    card = new SampleDevCardParam10((int)CardTypeEnum.DigitControlBoard);
                    this.AddCard(card);
                    break;
                case 1:
                    card = new SampleDevCardParam10((int)CardTypeEnum.AnalogSampleBoard);
                    this.AddCard(card);
                    break;
                case 2:
                    for (int i = 0; i < 3; i++)
                    {
                        card = new SampleDevCardParam10((int)CardTypeEnum.DigitControlBoard);
                        this.AddCard(card);
                    }
                    card = new SampleDevCardParam10((int)CardTypeEnum.AnalogSampleBoard);
                    this.AddCard(card);
                    break;
                case 3:
                    card = new SampleDevCardParam10((int)CardTypeEnum.FSKSampleBoard);
                    this.AddCard(card);
                    break;
                default:
                    //DoNothing
                    break;


            }

        }
        public bool AddCard(SampleDevCardParam10 card)
        {
            if (ContainsCard(card)) return false;
            CardItems.Add(card);
            return true;
        }
        public bool ContainsCard(int cardNo)
        {
            foreach (SampleDevCardParam10 card in CardItems)
            {
                if (cardNo == card.CardNo)
                {
                    return true;
                }
            }
            return false;
        }
        public bool ContainsCard(SampleDevCardParam10 card)
        {
            return ContainsCard(card.CardNo);
        }



    }
    /// <summary>
    /// ToDo:暂时未做对通道类型的防护处理
    /// </summary>
    public class SampleDevCardParam10
    {
        [XmlAttribute]
        public int CardNo;
        [XmlAttribute("板类型")]
        public int CardType = 3;
        [XmlAttribute("预留参数")]
        public int resvParam = 0;
        [XmlElement("通道")]
        public List<SampleDevChannelParam10> ChannelItems = new List<SampleDevChannelParam10>();
        [XmlIgnore]
        private int track25HzRef = 47;
        [XmlIgnore]
        private bool HavePhase3Current;
        [XmlIgnore]
        private static readonly int[] maxChannelsAboutTable
            = new int[]{48, 1,95,48,0,
                        0, 0, 0, 0,18,
                        8, 8, 8, 8,8
                       };
        #region
        public SampleDevCardParam10()
        {
        }
        public SampleDevCardParam10(int cardType)
        {
            if (CardType == (int)CardTypeEnum.DigitSampleBoard)
            {
                for (int i = 0; i < 48; i++)
                {
                    SampleDevChannelParam10 channel = new SampleDevChannelParam10(2);
                    ChannelItems.Add(channel);
                }
            }
        }
        public bool Add(SampleDevChannelParam10 param)
        {
            if (!ChannelTypeAttribFactory.Check(param.ChannelType, CardType)) return false;
            ChannelItems.Add(param);
            return true;
        }
        public bool Add(int channelNo, SampleDevChannelParam10 channel)
        {
            if (channelNo < ChannelItems.Count)
            {
                if (ChannelItems[channelNo].ChannelType != 0xf0) return false;
                ChannelItems[channelNo] = channel;

            }
            for (int i = ChannelItems.Count; i < channelNo; i++)
            {
                SampleDevCardParam10 emptyChannel = new SampleDevCardParam10();
            }
            return true;
        }
        /// <summary>
        /// 添加一个25Hz轨道电路
        /// </summary>
        /// <param name="force">如果参考通道已被占用是否强制替换</param>
        /// <returns></returns>
        public bool AddTrack25Hz(int channelNo, bool force)
        {
            if (ChannelItems.Count > track25HzRef)
            {
                if (ChannelItems[track25HzRef].ChannelType != 0x33 && force == false) return false;

            }
            else
            {
                this.Add(track25HzRef, new SampleDevChannelParam10());

            }

            ChannelItems[track25HzRef].ChannelType = 0x33;
            ChannelItems[track25HzRef].BytesCount = 6;

            this.Add(channelNo, new SampleDevChannelParam10());
            ChannelItems[track25HzRef].ChannelType = 0x33;
            ChannelItems[track25HzRef].RelatedCard1 = this.CardNo;
            ChannelItems[track25HzRef].RelatedChannel1 = this.track25HzRef;
            return true;
        }
        /// <summary>
        /// 从后向前查找一个空通道如无空通道返回 -1
        /// </summary>
        /// <returns></returns>
        public int FindUnusedChannel()
        {
            int i = 44;
            if (ChannelItems[i].ChannelType != 0xff) return -1;
            for (i = ChannelItems.Count - 4; i > 0; i--)
            {
                if (ChannelItems[i - 1].ChannelType != 0xf0) break;

            }
            return i;
        }

        /// <summary>
        /// 添加一个25Hz轨道电路
        /// </summary>
        /// <param name="force">如果参考通道已被占用是否强制替换</param>
        /// <returns></returns>
        public bool AddTrack25Hz(bool force)
        {
            int index = FindUnusedChannel();
            if (index < 0) return false;
            AddTrack25Hz(index, force);
            return true;
        }
        #endregion
    }
    public class SampleDevChannelParam10
    {
        [XmlAttribute("通道号")]
        public int ChannelNo;
        [XmlAttribute("通道类型")]
        public int ChannelType=0xf0;
        [XmlAttribute("字节数")]
        public int BytesCount=2;
        [XmlAttribute("关联板号1")]
        public int RelatedCard1=0xff;
        [XmlAttribute("关联通道号1")]
        public int RelatedChannel1;
        [XmlAttribute("关联板号2")]
        public int RelatedCard2=0xff;
        [XmlAttribute("关联通道号2")]
        public int RelatedChannel2=0xff;
        [XmlAttribute("附加参数")]
        public int OtherParam;
        [XmlIgnore]
        public  ChannelTypeAttrib Attrib=null;
        public SampleDevChannelParam10()
        {

        }
        public SampleDevChannelParam10(int type)
        {
            this.ChannelType = type;
            this.Attrib=ChannelTypeAttribFactory.GetAttrib(type);
            this.BytesCount = Attrib.SetBytes;
            this.RelatedCard1 = Attrib.RefCard1;
            this.RelatedCard2 = Attrib.RefCard2;
            this.RelatedChannel1 = Attrib.RefChanel1;
            this.RelatedChannel2=Attrib.RefChanel2;
            this.OtherParam = Attrib.OtherParam;
        }


    }

  
}
